﻿using System;
using System.IO;
using log4net;
using WinForms.Framework.Core;

namespace WinForms.Framework.Utility
{
    /// <summary>
    /// log4net を使用してログの書き込みを行うクラスです。
    /// </summary>
    public class Logger : ILogger
    {
        /// <summary>
        /// ログの書き込みを実装した ILog インターフェースです。
        /// </summary>
        private readonly ILog _log;

        #region Constructor
        /// <summary>
        /// 既定の構成ファイルを使用して Logger クラスの新しいインスタンスを初期化します。
        /// </summary>
        /// <param name="type">ログを実装する対象のオブジェクトを設定します。</param>
        public Logger(Type type)
            : this(type, "log4net.config")
        {
        }

        /// <summary>
        /// 既定の構成ファイルを使用して Logger クラスの新しいインスタンスを初期化します。
        /// </summary>
        /// <param name="name">ログを実装する Logger name を設定します。</param>
        public Logger(string name)
            : this(name, "log4net.config")
        {
        }

        /// <summary>
        /// 構成ファイルを指定して Logger クラスの新しいインスタンスを初期化します。
        /// </summary>
        /// <param name="type">ログを実装する対象の型を設定します。</param>
        /// <param name="log4NetConfigFile">log4net 構成ファイルのパスを設定します。</param>
        public Logger(Type type, string log4NetConfigFile)
        {
            log4net.Config.XmlConfigurator.Configure(new FileInfo(log4NetConfigFile));
            _log = LogManager.GetLogger(type);
        }

        /// <summary>
        /// 構成ファイルを指定して Logger クラスの新しいインスタンスを初期化します。
        /// </summary>
        /// <param name="name">ログを実装する Logger name を設定します。</param>
        /// <param name="log4NetConfigFile">log4net 構成ファイルのパスを設定します。</param>
        public Logger(string name, string log4NetConfigFile)
        {
            log4net.Config.XmlConfigurator.Configure(new FileInfo(log4NetConfigFile));
            _log = LogManager.GetLogger(name);
        }
        #endregion

        #region Method
        /// <summary>
        /// 文字列をデバッグログ情報に書き込みます。
        /// </summary>
        /// <param name="msg">ログに書き込む内容を設定します。</param>
        public void Debug(object msg)
        {
            _log.Debug(msg);
        }

        /// <summary>
        /// 書式指定された文字列をデバッグログ情報に書き込みます。
        /// </summary>
        /// <param name="format">複合書式指定文字列を設定します。</param>
        /// <param name="args">0 個以上の書式設定対象オブジェクトを含んだオブジェクト配列を設定します。</param>
        public void Debug(string format, params object[] args)
        {
            _log.DebugFormat(format, args);
        }

        /// <summary>
        /// 文字列をインフォメーションログ情報に書き込みます。
        /// </summary>
        /// <param name="msg">ログに書き込む内容を設定します。</param>
        public void Info(object msg)
        {
            _log.Info(msg);
        }

        /// <summary>
        /// 書式指定された文字列をインフォメーションログ情報に書き込みます。
        /// </summary>
        /// <param name="format">複合書式指定文字列を設定します。</param>
        /// <param name="args">0 個以上の書式設定対象オブジェクトを含んだオブジェクト配列を設定します。</param>
        public void Info(string format, params object[] args)
        {
            _log.InfoFormat(format, args);
        }

        /// <summary>
        /// 文字列をエラーログ情報に書き込みます。
        /// </summary>
        /// <param name="msg">ログに書き込む内容を設定します。</param>
        public void Error(object msg)
        {
            _log.Error(msg);
        }

        /// <summary>
        /// 書式指定された文字列をエラーログ情報に書き込みます。
        /// </summary>
        /// <param name="format">複合書式指定文字列を設定します。</param>
        /// <param name="args">0 個以上の書式設定対象オブジェクトを含んだオブジェクト配列を設定します。</param>
        public void Error(string format, params object[] args)
        {
            _log.ErrorFormat(format, args);
        }

        /// <summary>
        /// 文字列を致命的なエラーログ情報に書き込みます。
        /// </summary>
        /// <param name="msg">ログに書き込む内容を設定します。</param>
        public void Fatal(object msg)
        {
            _log.Fatal(msg);
        }

        /// <summary>
        /// 書式指定された文字列を致命的なエラーログ情報に書き込みます。
        /// </summary>
        /// <param name="format">複合書式指定文字列を設定します。</param>
        /// <param name="args">0 個以上の書式設定対象オブジェクトを含んだオブジェクト配列を設定します。</param>
        public void Fatal(string format, params object[] args)
        {
            _log.FatalFormat(format, args);
        }
        #endregion
    }
}
